package com.wx.house.manager.api.building.service.impl;

import com.wx.house.common.base.UserInfoUtil;
import com.wx.house.common.exception.BusinessException;
import com.wx.house.common.util.IDUtils;
import com.wx.house.common.util.StringUtil;
import com.wx.house.core.mapper.building.BChargeTemplateMapper;
import com.wx.house.core.mapper.building.BuildingMapper;
import com.wx.house.core.mapper.building.BuildingRoomMapper;
import com.wx.house.core.mapper.fileupload.AttaUploadMapper;
import com.wx.house.core.pojo.base.UserInfo;
import com.wx.house.core.pojo.dto.building.*;
import com.wx.house.core.pojo.po.building.BChargeTemplate;
import com.wx.house.core.pojo.po.building.BuildingRoom;
import com.wx.house.core.pojo.state.BuildHireEnum;
import com.wx.house.core.pojo.state.LogicalDeleteEnum;
import com.wx.house.core.pojo.vo.BuildingSimpleVo;
import com.wx.house.core.pojo.vo.BuildingVo;
import lombok.RequiredArgsConstructor;

import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wx.house.core.pojo.po.building.Building;
import com.wx.house.manager.api.building.service.BuildingService;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author ：罗棋
 * @Email ：58428467@qq.com
 * @date ：Created in 2019/10/28 上午 11:56
 * @description：${description}
 * @version: ：V$version
 */
@Service
@RequiredArgsConstructor
public class BuildingServiceImpl extends ServiceImpl<BuildingMapper, Building> implements BuildingService {
private final BuildingMapper buildingMapper;
private final BuildingRoomMapper buildingRoomMapper;
private final BChargeTemplateMapper bChargeTemplateMapper;
private final AttaUploadMapper attaUploadMapper;

@Override
public List<BuildingVo> selectBuildingVoList(String mAccId, String buildingName, Integer province, Integer city, Integer county) {
	return buildingMapper.selectBuildingVoList(mAccId, buildingName, province, city, county);
}

@Override
public List<BuildingSimpleVo> selectBuildingSimpleVoList(String mAccId, String buildingName, Integer province, Integer city, Integer county) {
	return buildingMapper.selectBuildingSimpleVoList(mAccId, buildingName, province, city, county, null, null);
}

@Override
public void insertBuilding(InsertBuildingDto dto) {
	if (buildingMapper.selectByBuildName(dto.getBuildingName()) != null)
		throw new BusinessException("楼宇 " + dto.getBuildingName() + " 已经存在");
	
	UserInfo userInfo = UserInfoUtil.userInfo();
	String buildingId = IDUtils.createUUId();
	Building building = new Building();
	building.setId(buildingId);
	building.setBuildName(dto.getBuildingName());
	building.setProvince(dto.getProvince());
	building.setCity(dto.getCity());
	building.setCounty(dto.getCounty());
	building.setAddress(dto.getAddress());
	building.setAddTime(new Date());
	building.setOperation(userInfo.getRealName());
	building.setOperationTime(building.getAddTime());
	building.setLogicalState(LogicalDeleteEnum.NORMAL.state);
	building.setMAccId(userInfo.getMAccId());
	building.setLongitude(dto.getLongitude());
	building.setLatitude(dto.getLatitude());
	
	List<BuildingRoomDto> buildingRoomDtoList =
			dto.getBuildingRoomDtoList()
					.stream()
					.collect(
							Collectors.collectingAndThen(
									Collectors.toCollection(
											() -> new TreeSet<>(Comparator.comparing(room -> room.getFloorId() + room.getDoorNumber()))),
									ArrayList::new
							)
					);
	
	List<BuildingRoom> insertBuildingRoomDtoList = new ArrayList<>();
	buildingRoomDtoList.forEach(buildingRoomDto -> {
		BuildingRoom buildingRoom = new BuildingRoom();
		buildingRoom.setId(IDUtils.createUUId());
		buildingRoom.setBuildingId(buildingId);
		buildingRoom.setFloorId(buildingRoomDto.getFloorId());
		buildingRoom.setDoorNumber(buildingRoomDto.getDoorNumber());
		buildingRoom.setRoomSpace(buildingRoomDto.getRoomSpace());
		buildingRoom.setAddTime(new Date());
		buildingRoom.setBuildType(BuildHireEnum.WAITHIRE.state);
		buildingRoom.setOperation(userInfo.getRealName());
		buildingRoom.setOperationTime(buildingRoom.getAddTime());
		buildingRoom.setHistoryWater(0);
		buildingRoom.setHistoryElectric(0);
		buildingRoom.setHistoryGas(0);
		buildingRoom.setUpdateTime(new Date());
		insertBuildingRoomDtoList.add(buildingRoom);
	});
	BChargeTemplate bChargeTemplate = new BChargeTemplate();
	bChargeTemplate.setId(IDUtils.createUUId());
	bChargeTemplate.setBuildId(buildingId);
	bChargeTemplate.setBuildWater(dto.getWaterRate());
	bChargeTemplate.setBuildElectric(dto.getPowerRate());
	bChargeTemplate.setBuildGas(dto.getGasRate());
	bChargeTemplate.setBuildProperty(dto.getPropertyRateRate());
	bChargeTemplate.setAddTime(new Date());
	bChargeTemplate.setOperation(userInfo.getRealName());
	bChargeTemplate.setOperationTime(bChargeTemplate.getAddTime());
	bChargeTemplate.setLogicalState(LogicalDeleteEnum.NORMAL.state);
	
	if (buildingMapper.insert(building) != 1) throw new BusinessException("楼宇添加失败");
	if (buildingRoomMapper.insertList(insertBuildingRoomDtoList) != insertBuildingRoomDtoList.size())
		throw new BusinessException("楼宇添加失败");
	if (bChargeTemplateMapper.insert(bChargeTemplate) != 1) throw new BusinessException("楼宇添加失败");
	
	attaUploadMapper.updateResourceIdByIdIn(buildingId, new ArrayList<String>() {{
		add(dto.getBuildImgId());
	}});
}

@Override
public Building selectByBuildName(String buildingName) {
	return buildingMapper.selectByBuildName(buildingName);
}

@Override
public void deleteBuilding(String id) {
	if (buildingRoomMapper.roomWaitHireNumber(id) > 1) {
		throw new BusinessException("此楼宇还有出租中的房间，不能删除");
	}
	//删除楼宇，删除房间和价格模板
	buildingMapper.deleteById(id);
	buildingRoomMapper.deleteByBuildingId(id);
	bChargeTemplateMapper.deleteByBuildId(id);
}

@Override
public List<BuildingRoom> insertBuildingRoom(List<InsertBuildingRoomDto> insertBuildingRoomDtoList) {
	UserInfo userInfo = UserInfoUtil.userInfo();
	
	List<InsertBuildingRoomDto> buildingRoomDtoList =
			insertBuildingRoomDtoList
					.stream()
					.collect(
							Collectors.collectingAndThen(
									Collectors.toCollection(
											() -> new TreeSet<>(Comparator.comparing(room -> room.getFloorId() + room.getDoorNumber()))),
									ArrayList::new
							)
					);
	//楼栋的全部房间
	List<BuildingRoom> buildingRooms = buildingRoomMapper.selectByBuildingId(insertBuildingRoomDtoList.get(0).getBuildingId());
	
	
	List<BuildingRoom> resultVoList = new ArrayList<>();
	
	//去掉已有的房间
	buildingRooms.forEach(e -> {
		boolean b = buildingRoomDtoList.removeIf(room -> e.getFloorId().equals(room.getFloorId()) && e.getDoorNumber().equals(room.getDoorNumber()));
		if (b) resultVoList.add(e);
	});
	if (buildingRoomDtoList.size() == 0) return resultVoList;
	
	List<BuildingRoom> resultList = new ArrayList<>();
	buildingRoomDtoList.forEach(buildingRoomDto -> {
		BuildingRoom buildingRoom = new BuildingRoom();
		buildingRoom.setId(IDUtils.createUUId());
		buildingRoom.setBuildingId(buildingRoomDto.getBuildingId());
		buildingRoom.setFloorId(buildingRoomDto.getFloorId());
		buildingRoom.setDoorNumber(buildingRoomDto.getDoorNumber());
		buildingRoom.setRoomSpace(buildingRoomDto.getRoomSpace());
		buildingRoom.setAddTime(new Date());
		buildingRoom.setBuildType(BuildHireEnum.WAITHIRE.state);
		buildingRoom.setOperation(userInfo.getRealName());
		buildingRoom.setOperationTime(buildingRoom.getAddTime());
		resultList.add(buildingRoom);
	});
	
	if (buildingRoomMapper.insertList(resultList) != resultList.size()) throw new BusinessException("新增失败");
	return resultVoList;
}

@Override
public List<BuildingRoom> deleteBuildingRoom(List<String> idList) {
	List<BuildingRoom> buildingRooms = buildingRoomMapper.selectByIdIn(idList);
	if (buildingRooms.size() == 0) return null;
	List<String> resultIdList = buildingRooms
			                            .stream()
			                            .filter(e -> e.getBuildType().equals(BuildHireEnum.WAITHIRE.state))
			                            .map(BuildingRoom::getId)
			                            .collect(Collectors.toList());
	
	if (buildingRoomMapper.deleteByIdIn(resultIdList) != resultIdList.size()) {
		throw new BusinessException("删除失败");
	}
	
	return buildingRooms
			       .stream()
			       .filter(e -> e.getBuildType().equals(BuildHireEnum.HIRED.state))
			       .collect(Collectors.toList());
}

@Override
public void updateBuildingRoom(List<UpdateBuildingRoomDto> updateBuildingRoomDtoList) {
	try {
		updateBuildingRoomDtoList.forEach(e -> {
			BuildingRoom buildingRoom = new BuildingRoom();
			buildingRoom.setId(e.getId());
			if (StringUtil.isNotEmpty(e.getFloorId())) buildingRoom.setFloorId(e.getFloorId());
			if (StringUtil.isNotEmpty(e.getDoorNumber())) buildingRoom.setDoorNumber(e.getDoorNumber());
			if (StringUtil.isNotEmpty(e.getRoomSpace())) buildingRoom.setRoomSpace(e.getRoomSpace());
			buildingRoomMapper.updateById(buildingRoom, buildingRoom.getId());
		});
	} catch (Exception e) {
		e.printStackTrace();
		throw new BusinessException("房间更新失败");
	}
}

@Override
public void updateBuilding(UpdateBuildingDto updateBuildingDto) {
	//step1 更新楼宇信息
	Building building = new Building();
	building.setId(updateBuildingDto.getId());
	if (StringUtil.isNotEmpty(updateBuildingDto.getBuildingName())) {
		building.setBuildName(updateBuildingDto.getBuildingName());
	}
	if (StringUtil.isNotEmpty(updateBuildingDto.getAddress())) {
		building.setAddress(updateBuildingDto.getAddress());
	}
	if (updateBuildingDto.getCity() != null) {
		building.setCity(updateBuildingDto.getCity());
	}
	if (updateBuildingDto.getCounty() != null) {
		building.setCounty(updateBuildingDto.getCounty());
	}
	if (updateBuildingDto.getProvince() != null) {
		building.setProvince(updateBuildingDto.getProvince());
	}
	if (StringUtil.isNotEmpty(updateBuildingDto.getLongitude())) {
		building.setLongitude(updateBuildingDto.getLongitude());
	}
	if (StringUtil.isNotEmpty(updateBuildingDto.getLatitude())) {
		building.setLatitude(updateBuildingDto.getLatitude());
	}
	
	
	BChargeTemplate bChargeTemplate = new BChargeTemplate();
	bChargeTemplate.setBuildId(updateBuildingDto.getId());
	
	if (updateBuildingDto.getWaterRate() != null)
		bChargeTemplate.setBuildWater(updateBuildingDto.getWaterRate());
	if (updateBuildingDto.getGasRate() != null)
		bChargeTemplate.setBuildGas(updateBuildingDto.getGasRate());
	if (updateBuildingDto.getPowerRate() != null)
		bChargeTemplate.setBuildElectric(updateBuildingDto.getPowerRate());
	if (updateBuildingDto.getPropertyRateRate() != null)
		bChargeTemplate.setBuildProperty(updateBuildingDto.getPropertyRateRate());
	
	if (updateBuildingDto.getWaterRate() != null
			    || updateBuildingDto.getGasRate() != null
			    || updateBuildingDto.getPowerRate() != null
			    || updateBuildingDto.getPropertyRateRate() != null)
		bChargeTemplateMapper.updateByBuildId(bChargeTemplate, updateBuildingDto.getId());
	
	buildingMapper.updateById(building, updateBuildingDto.getId());
	
	if (StringUtil.isNotEmpty(updateBuildingDto.getBuildImgId())) {
		if(ObjectUtils.isNotEmpty(attaUploadMapper.selectResourceId(updateBuildingDto.getId()))) {
			if((attaUploadMapper.deleteResourceId(updateBuildingDto.getId()))==0) {
				throw new BusinessException("租户新增绑定附件异常,重新提交审核");
			}
		}
		attaUploadMapper.updateResourceIdByIdIn(updateBuildingDto.getId(), new ArrayList<String>() {{
			add(updateBuildingDto.getBuildImgId());
		}});
	}
}

@Override
public void discardBuildingRoom(String roomId,String buildType) {
	try {
		buildingRoomMapper.discardBuildingRoom(roomId, buildType);
	} catch (Exception e) {
		throw new BusinessException("废弃房间失败");
	}
}

}
